﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Web;
using System.IO;
using Devfw.OpenAuth;
using Devfw;
using System.Collections;

namespace Devfw.OpenAuth.Platform
{
    public class RenrenV2 : Provider20Base
    {
        public const string Scope = "publish_feed publish_comment publish_share publish_blog";
        public string CallBackUrl
        {
            get;
            set;
        }

        private const string authorizeUrl = "https://graph.renren.com/oauth/authorize";
        private const string accesstokenUrl = "https://graph.renren.com/oauth/token";
        private const string sessionkeyUrl = "http://graph.renren.com/renren_api/session_key";
        private const string APIServerUrl = "http://api.renren.com/restserver.do";
        public RenrenV2(string apiKey, string secretKey)
            : base(apiKey, secretKey)
        { }
        public RenrenV2(string apiKey, string secretKey, string accessToken, string refreshToken)
            : base(apiKey, secretKey, accessToken, refreshToken)
        { }

        public override string authorize()
        {
          //  string query = string.Format("response_type=code&client_id={0}&redirect_uri={1}&scope={2}", APIKey, CallBackUrl,Scope);
           // HttpContext.Current.Response.Redirect(OpenAuthHelper.CombinUrl(authorizeUrl, query));
            return string.Empty;
        }


        public string GetAuthorizeUrl(string extre)
        {
            string query = string.Format("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&extre={3}", APIKey, HttpUtility.UrlEncode(CallBackUrl), Scope, HttpUtility.UrlEncode(extre) );
            return OpenAuthHelper.CombinUrl(authorizeUrl, query);
        }

        public override string getAccessToken(string authorization_code,string state)
        {
            string query = string.Format("grant_type=authorization_code&code={0}&client_id={1}&client_secret={2}&redirect_uri={3}", authorization_code, APIKey, SecretKey,HttpUtility.UrlEncode( CallBackUrl) );
            string response = OpenAuthHelper.WebRequest(HttpWebMethod.POST, OpenAuthHelper.CombinUrl(accesstokenUrl, query), string.Empty, string.Empty);
            
            return response;
        }

        public override string getRefreshToken()
        {
            string query = string.Format("grant_type=refresh_token&refresh_token={0}&client_id={1}&client_secret={2}", RefreshToken, APIKey, SecretKey);
            string response = OpenAuthHelper.WebRequest(HttpWebMethod.POST, OpenAuthHelper.CombinUrl(accesstokenUrl, query), string.Empty, string.Empty);

            return response;
        }

        private JsonObject getSessionKeyJson(string access_token)
        {
            string query = string.Format("oauth_token={0}", HttpUtility.UrlEncode(access_token));
            string response = OpenAuthHelper.WebRequest(HttpWebMethod.POST, OpenAuthHelper.CombinUrl(sessionkeyUrl, query), string.Empty, string.Empty);
            return new JsonObject(response);
        }

        public string getSessionKey(string access_token)
        {
            JsonObject obj = getSessionKeyJson(access_token);
            return obj["renren_token"].GetValue<JsonObject>()["session_key"].Value;
        }

        public SessionKey getSessionEntity()
        {
            var key = string.Format("Devfw.OpenAuth.Platform.RenrenV2.AccessToken.{0}", AccessToken);
            SessionKey sessionInfo = null;// CacheHelper.GetCachedObject<SessionKey>(key);
            if (sessionInfo == null)
            {

                var ret = getSessionKeyJson(AccessToken);
                var sessionKey = ret["renren_token"].GetValue<JsonObject>()["session_key"].Value;
                if (!string.IsNullOrEmpty(sessionKey))
                {
                    long dummy;
                    if(!long.TryParse( ret["renren_token"].GetValue<JsonObject>()["expires_in"].Value, out dummy ))
                    {
                        dummy = 0;
                    }

                    var item = new SessionKey()
                    {
                        ExpiresIn = dummy,
                        Key = ret["renren_token"].GetValue<JsonObject>()["session_key"].Value,
                        Secret = ret["renren_token"].GetValue<JsonObject>()["session_secret"].Value,
                        UserID = ret["user"].GetValue<JsonObject>()["id"].Value,
                        RowTime = DateTime.Now
                    };

                   sessionInfo = item;//CacheHelper.GetCachedObject<SessionKey>(key, (int)item.ExpiresIn, delegate(){return item;});
                }
            }

            return sessionInfo;
        }

        public string getUserID(string access_token)
        {
            JsonObject obj = getSessionKeyJson(access_token);
            return obj["user"].GetValue<JsonObject>()["id"].Value;
        }

        /// <summary>
        /// 调用新鲜事的接口参数
        /// </summary>
        /// <param name="template_id">模版id</param>
        /// <param name="title_data">标题json字符串</param>
        /// <param name="body_data">内容json字符串</param>
        /// <param name="attachment">图片附件json字符串{"src":"图片地址","href":"图片链接"}</param>
        /// <param name="desc">用户输入的自定义内容</param>
        /// <param name="action_links">活动链接json字符串{"href":"链接地址","text":"链接说明"}</param>
        /// <returns></returns>
        public ParameterCollection getFeedPublishParameters(string template_id,string title_data,string body_data,string attachment,string desc,string action_links)
        {
            return new ParameterCollection()
                {
                    new Parameter( "api_key", HttpUtility.UrlEncode(APIKey), ParameterType.Get ),
                    new Parameter( "method", HttpUtility.UrlEncode("feed.publish"), ParameterType.Get ),
                    new Parameter( "call_id", HttpUtility.UrlEncode( DateTime.Now.Millisecond.ToString()), ParameterType.Get ),
                    new Parameter( "v", HttpUtility.UrlEncode("1.0"), ParameterType.Get ),
                    new Parameter( "session_key", HttpUtility.UrlEncode(getSessionKey(AccessToken)), ParameterType.Get ),
                    new Parameter( "template_id", HttpUtility.UrlEncode(template_id), ParameterType.Get ),
                    new Parameter( "title_data", HttpUtility.UrlEncode(title_data), ParameterType.Get ),
                    new Parameter( "body_data", HttpUtility.UrlEncode(body_data), ParameterType.Get ),
                    new Parameter( "attachment", HttpUtility.UrlEncode(attachment), ParameterType.Get ),
                    new Parameter( "format", HttpUtility.UrlEncode("JSON"), ParameterType.Get ),
                    new Parameter( "desc", HttpUtility.UrlEncode(desc), ParameterType.Get ),
                    new Parameter( "action_links", HttpUtility.UrlEncode(action_links), ParameterType.Get )
                };
        }
        public static string GetMd5(string md5str)
        {
            return System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(md5str, "MD5");
        }
        private string getSign(ParameterCollection collect)
        {
            collect.Sort();
            string pstr = "";
            foreach (Parameter p in collect)
            {
                pstr += string.Format("{0}={1}", p.Name, p.Value);
            }
            pstr += SecretKey;

            return GetMd5(pstr);
        }

        /// <summary>
        /// 调用api接口
        /// </summary>
        /// <param name="collect">参数集</param>
        /// <returns></returns>
        public string CallApiRestserver(ParameterCollection collect)
        {
            collect.Add(new Parameter("v", "1.0", ParameterType.Get));
            collect.Add(new Parameter("format", "XML", ParameterType.Get));
            collect.Add(new Parameter("sig", HttpUtility.UrlEncode(getSign(collect)), ParameterType.Get));
            

            string query   = OpenAuthHelper.ToQueryString( collect.GetParameters(ParameterType.Get));
            string response = OpenAuthHelper.WebRequest(HttpWebMethod.POST, OpenAuthHelper.CombinUrl(APIServerUrl, query), string.Empty, string.Empty);

            return response;
        }

      
        public string GetUserInfo(string uids)
        {
            var session = getSessionEntity();
            if (session != null)
            {
                uids = string.IsNullOrEmpty(uids) ? session.UserID : uids;
                var parameters = new ParameterCollection(){
                    new  Parameter("api_key", APIKey ,ParameterType.Get ),
                    new  Parameter("method","users.getInfo",ParameterType.Get ),
                    new  Parameter("uids",uids,ParameterType.Get ),
                    new  Parameter("fields","uid,name,sex,star,zidou,vip,birthday,email_hash,tinyurl,headurl,mainurl,hometown_location,work_history,university_history",ParameterType.Get ),
                    new  Parameter("session_key",session.Key,ParameterType.Get )
                };

               return CallApiRestserver(parameters);
            }

            return string.Empty;
        }


        public string FeedPublishFeed(string name, string description, string url, string image)
        {
            if (!string.IsNullOrEmpty( AccessToken ) )
            {
                var parameters = new ParameterCollection(){
                    new  Parameter("access_token", AccessToken ,ParameterType.Get ),
                    new  Parameter("method","feed.publishFeed",ParameterType.Get ),
                    new  Parameter("name",name,ParameterType.Get ),
                    new  Parameter("description",description,ParameterType.Get ),
                    new  Parameter("url",url,ParameterType.Get ),
                    new  Parameter("image",image,ParameterType.Get )
                };

                return CallApiRestserver(parameters);
            }

            return string.Empty;
        }

    }

    public class SessionKey
    {
        public string Key { get; set; }
        public string Secret { get; set; }
        public long ExpiresIn { get; set; }
        public string UserID { get; set; }
        public DateTime RowTime { get; set; }
    }
}
